package band.wukong.practice.javase.core.tips;

/**
 * Descriptiocn: 编写一个截取字符串的函数
 * 输入为一个字符串和字节数，输出为按字节截取的字符串。 但是要保证汉字不被截半个，
 * 如“我ABC”4，应该截为“我AB”，输入“我ABC汉DEF”，6，应该输出为“我ABC”而不是“我ABC+汉的半个”。
 * Author: jsun
 * Date: 2010-2-21 9:54:45
 */
public class CNStringSpliter {
    public static void main(String[] args) throws Exception {

        String s = "i老虎u";
        int num = 3;
        System.out.println("split(s) = " + split(s, num));
        System.out.println("split2(s) = " + split2(s, num, -1));

    }

    public static String split(String s, int byteNum) throws Exception {
        //入参校验
        if (null == s || 0 == s.trim().length()) {
            throw new Exception("输入参数：字符串不能为空");
        }
        if (byteNum <= 0) {
            throw new Exception("输入参数：字节数必须大于0");
        }
        //将字符串转换为字节数组
        byte array[] = s.getBytes("GBK");
        if (byteNum > array.length) {
            throw new Exception("输入参数：字节数不能大于" + array.length);
        }
        //汉字字节长度
        int cnByteNum = 0;
        //累计汉字字节数
        for (int i = 0; i < byteNum; i++) {
            if (array[i] < 0) {//汉字字节.汉字都为负数。见com.jsun.javase.tips.TestEncoding.java
                ++cnByteNum;
            }
        }
        //如果汉字字节长度不是2的倍数，则舍去一个字节
        int result = (cnByteNum % 2 == 0) ? byteNum : byteNum - 1;

        return new String(array, 0, result, "GBK");
    }

    /**
     * Java中1个char类型的变量可存储任意编码的1个字符，如1个ASC码和或1个中文字符，
     * 例如：含有3个ASC和含有3个汉字字符的字符串长度是一样的： "1ac".length()==3;  "你好a".length()=3;
     * 但上述两个字符串所占的byte是不一样的，前者是3，后者是5（1个汉字2byte）。
     * 请编写函数:
     *     public static String leftStr(String source, int maxByteLen)
     * 从source中取最大maxByteLen个byte的子串。
     * 当最后一个byte恰好为一个汉字的前半个字节时，舍弃此byte。例如：
     *     String str="我LRW爱JAVA";
     *     leftStr(str,1,-1)=="";
     *     leftStr(str,2,-1)=="我";
     *     leftStr(str,4,-1)=="我LR";
     *     leftStr(str,11,-1)=="我LRW";
     * 当最后一个byte恰好为一个汉字的前半个字节时，补全汉字（多取一个字节）。例如：
     *     String str="我LRW爱JAVA";
     *     leftStr(str,1,1)=="我";
     *     leftStr(str,2,1)=="我";
     *     leftStr(str,4,1)=="我LR";
     *     leftStr(str,11,1)=="我LRW爱";
     *
     * @param source 原始字符串
     * @param maxByteLen 截取的字节数
     * @param flag 表示处理汉字的方式。1表示遇到半个汉字时补全，-1表示遇到半个汉字时舍弃
     * @return 截取后的字符串
     * @throws Exception
     */
    public static String split2(String source, int maxByteLen, int flag) throws Exception {
        if(source == null || maxByteLen <= 0){
            return "";
        }
        byte[] bStr = source.getBytes("GBK");
        if(maxByteLen >= bStr.length)return source;
        String cStr = new String(bStr, maxByteLen - 1, 2, "GBK");
        if(cStr.length() == 1 && source.contains(cStr)){
            maxByteLen += flag;
        }
        return new String(bStr, 0, maxByteLen, "GBK");
    }
    
}
